//
// Created by 颖滴哦 on 2023/3/13.
//
/*
 * 1.关闭进程不需要的文件描述符，否则程序将在第一个进程到达35之前耗尽资源。
 * 2.一旦第一个进程达到35，它应该等待整个管道终止，包括所有子代、孙辈等。因此，只有在打印完所有输出之后，以及在所有其他素数进程退出之后，主素数进程才会退出。
 * 3.当管道的写端关闭时，read返回零。
 * 4.最简单的方法是直接将32位（4字节）的整数写入管道，而不是使用格式化的ASCII I/O。
 * 5.您应该仅在需要时在管道中创建流程。
 */
#include "kernel/types.h"
#include "user/user.h"
void child(int p[]){
    int fnum;
    close(p[1]);
    if(read(p[0], &fnum, sizeof(int))==0){
        close(p[0]);
        exit(0);
    }
    printf("prime %d\n", fnum);
    int p2[2];
    pipe(p2);
    if(fork()==0){
        child(p2);
    } else{
        int i;
        while (read(p[0], &i, sizeof(int))!=0){
            if(i%fnum!=0){
                write(p2[1],&i,sizeof (int));
            }
        }
        close(p2[0]);
        close(p2[1]);
        wait(0);
    }
    exit(0);
}

int main() {
    printf("primes\n");
    int num;
    int p[2];
    pipe(p);
    num = 2;
    if (fork() > 0) {//父
        close(p[0]);
        while (num <= 35) {
            write(p[1], &num, sizeof(int));
            num++;
        }
        close(p[1]);
        wait(0);
    } else {//子
        child(p);
    }
    exit(0);
}